<!-- components/Table/Table.vue -->
<template>
  <div
    class="ds-table"
    :class="[`table-size-${size}`, { 'table-stripe': stripe, 'table-border': border }]"
    ref="tableRef"
    expandable
  >
    <!-- 导出按钮 -->
    <div v-if="showExport" class="table-export">
      <button @click="handleExport">
        {{ exportButtonText }}
      </button>
    </div>

    <!-- 加载遮罩层 -->
    <div v-if="loading" class="loading-mask">
      <div class="loading-content">
        <slot name="loading">
          <div class="default-loading">
            <div class="loading-spinner"></div>
            <div class="loading-text">{{ loadingText }}</div>
          </div>
        </slot>
      </div>
    </div>

    <!-- 搜索框 -->
    <div v-if="showSearch" class="table-search">
      <input
        v-model="searchKeyword"
        placeholder="搜索..."
        @input="handleSearch"
        class="search-input"
        :disabled="loading"
      />
    </div>

    <!-- 表格容器 -->
    <div class="table-container" :style="{ height: fixedHeader ? fixedHeaderHeight : 'auto' }">
      <!-- 表头固定容器 -->
      <div v-if="fixedHeader" class="fixed-header-container">
        <table class="header-table" ref="headerTableRef">
          <colgroup>
            <col v-if="rowSelection" :style="{ width: selectionColumnWidth }">
            <col v-for="col in columns" :key="col.dataIndex" :style="{ width: col.width || 'auto' }">
          </colgroup>
          <thead>
            <tr>
              <!-- 选择列 -->
              <th 
                v-if="rowSelection" 
                :class="headerAlignClass"
                class="selection-column"
              >
                <div class="header-content">
                  <input
                    type="checkbox"
                    :checked="allSelected"
                    @change="toggleAllSelection"
                    :disabled="loading"
                  />
                </div>
                <div 
                  v-if="resizable" 
                  class="resize-handle"
                  @mousedown.prevent="startResize('selection', $event)"
                ></div>
              </th>
              
              <!-- 数据列 -->
              <th
                v-for="(col, colIndex) in columns"
                :key="col.dataIndex"
                :class="[headerAlignClass, { sortable: sortable && col.sortable }]"
              >
                <div class="header-content">
                  <slot :name="`header-${col.dataIndex}`" :column="col">
                    <span @click="handleSort(col)">
                      {{ col.title }}
                      <span v-if="sortable && col.sortable" class="sort-icon">
                        {{ sortedColumn.field === col.dataIndex ? 
                          (sortedColumn.order === 'asc' ? '↑' : '↓') : '' }}
                      </span>
                    </span>
                  </slot>
                </div>
                <div 
                  v-if="resizable" 
                  class="resize-handle"
                  @mousedown.prevent="startResize(colIndex, $event)"
                ></div>
              </th>
            </tr>
          </thead>
        </table>
      </div>

      <!-- 数据表格容器 -->
      <div class="body-container" @scroll="syncHeaderScroll">
        <table class="body-table" ref="bodyTableRef">
          <colgroup>
            <col v-if="rowSelection" :style="{ width: selectionColumnWidth }">
            <col v-for="col in columns" :key="col.dataIndex" :style="{ width: col.width || 'auto' }">
          </colgroup>
          <!-- 空状态 -->
          <tbody>
            <tr v-if="showEmpty" class="empty-row">
              <td :colspan="totalColumns">
                <slot name="empty">
                  <div class="empty-content">
                    <svg class="empty-icon" viewBox="0 0 1024 1024">
                      <path d="M832 320H192v448h640V320z m-64 384H256V384h512v320z m64-416h-64v-64h64v64z m0-128H192v64h640v-64zM128 256h64v512H128z m704 512h64V256h-64v512z"/>
                    </svg>
                    <div class="empty-text">{{ emptyText }}</div>
                  </div>
                </slot>
              </td>
            </tr>

            <!-- 数据行 -->
            <template
              v-for="(row, index) in displayData"
              :key="rowKey ? row[rowKey] : index"
            >
              <tr
                :class="{
                  'selected-row': isRowSelected(row),
                  'stripe-row': stripe && index % 2 === 0
                }"
                @click="handleRowClick(row)"
              >
                <!-- 选择列 -->
                <td
                  v-if="rowSelection"
                  :class="cellAlignClass"
                >
                  <input
                    type="checkbox"
                    :checked="isRowSelected(row)"
                    @change="toggleRowSelection(row)"
                    :disabled="loading"
                  />
                </td>

                <!-- 数据列 -->
                <td
                  v-for="col in columns"
                  :key="col.dataIndex"
                  :class="cellAlignClass"
                >
                  <!-- 如果是树形数据，添加缩进 -->
                  <template v-if="treeData && col.dataIndex === 'name'">
                    <span 
                      class="tree-indent" 
                      :style="{ paddingLeft: `${row._level * 20}px` }"
                    ></span>
                  </template>
                  <slot :name="`cell-${col.dataIndex}`" :row="row" :value="row[col.dataIndex]">
                    {{ row[col.dataIndex] }}
                  </slot>
                </td>
              </tr>
              <!-- 展开行 -->
              <tr v-if="expandable && expandedKeys.includes(row.id)" class="expanded-row">
                <td :colspan="columns.length + (rowSelection ? 1 : 0)">
                  <slot name="expanded-row" :row="row"></slot>
                </td>
              </tr>
            </template>
          </tbody>
        </table>
      </div>
      <div
        v-if="resizing"
        class="resize-line"
        :style="{ left: resizeLinePos + 'px' }"
      ></div>
    </div>

    <!-- 分页 -->
    <div v-if="pagination" class="table-pagination">
      <button
        :disabled="currentPage === 1 || loading"
        @click="changePage(currentPage - 1)"
      >
        上一页
      </button>
      <span>第 {{ currentPage }} 页 / 共 {{ totalPages }} 页</span>
      <button
        :disabled="currentPage >= totalPages || loading"
        @click="changePage(currentPage + 1)"
      >
        下一页
      </button>
    </div>
  </div>
</template>

<script setup>
import {
  ref,
  computed,
  watch,
  toRefs,
  onMounted,
  onBeforeUnmount,
  nextTick
} from 'vue'
import { utils, writeFile } from 'xlsx' // 需要安装xlsx库

const props = defineProps({
  // 数据相关
  data: {
    type: Array,
    default: () => []
  },
  columns: {
    type: Array,
    default: () => []
  },
  pagination: {
    type: Boolean,
    default: false
  },
  pageSize: {
    type: Number,
    default: 10
  },
  currentPage: {
    type: Number,
    default: 1
  },

  // 样式相关
  stripe: Boolean,
  border: Boolean,
  size: {
    type: String,
    default: 'medium',
    validator: v => ['small', 'medium', 'large'].includes(v)
  },
  headerAlign: {
    type: String,
    default: 'left',
    validator: v => ['left', 'center', 'right'].includes(v)
  },
  cellAlign: {
    type: String,
    default: 'left',
    validator: v => ['left', 'center', 'right'].includes(v)
  },

  // 功能相关
  rowSelection: Boolean,
  selectedRows: {
    type: Array,
    default: () => []
  },
  sortable: Boolean,
  sortedColumn: {
    type: Object,
    default: () => ({ field: null, order: null })
  },

  // 其他配置
  rowKey: String,
  virtualScroll: Boolean,
  showSearch: Boolean,
  emptyText: {
    type: String,
    default: '暂无数据'
  },
  // loading
  loading: {
    type: Boolean,
    default: false
  },
  loadingText: {
    type: String,
    default: '加载中...'
  },
  // 原有属性保持不变...
  resizable: { // 新增列宽调整属性
    type: Boolean,
    default: false
  },
  selectionColumnWidth: {
    type: String,
    default: '50px'
  },
  fixedHeader: Boolean,
  fixedHeaderHeight: {
    type: String,
    default: '400px'
  },
  treeData: {
    type: Boolean,
    default: false
  },
  expandedKeys: {
    type: Array,
    default: () => []
  },
  expandable: {
    type: Boolean,
    default: false
  },

  // 导出功能配置
  showExport: {
    type: Boolean,
    default: false
  },
  exportButtonText: {
    type: String,
    default: '导出数据'
  },
  exportMode: {
    type: String,
    default: 'current', // 'current' | 'all'
    validator: v => ['current', 'all'].includes(v)
  },
  exportFileName: {
    type: String,
    default: 'data'
  },
  exportType: {
    type: String,
    default: 'xlsx', // 'xlsx' | 'csv'
    validator: v => ['xlsx', 'csv'].includes(v)
  }
})

const emit = defineEmits([
  'update:currentPage',
  'update:selectedRows',
  'update:sortedColumn',
  'rowClick',
  'sortChange',
  'paginationChange',
  'update:columns', // 新增列更新事件
  'expand',
  'update:expandedKeys'
])

// 列宽调整相关状态
const tableRef = ref(null)
const headerTableRef = ref(null)
const bodyTableRef = ref(null)
const resizing = ref(false)
const resizeLinePos = ref(0)
const startX = ref(0)
const startWidth = ref(0)
const currentColumn = ref(null)

const startResize = (colIndex, event) => {
  if (!props.resizable) return
  
  resizing.value = true
  startX.value = event.clientX
  const headerTable = headerTableRef.value
  const bodyTable = bodyTableRef.value
  
  if (!headerTable || !bodyTable) return
  
  const headerCols = headerTable.querySelectorAll('col')
  const bodyCols = bodyTable.querySelectorAll('col')
  
  if (!headerCols.length || !bodyCols.length) return
  
  const col = headerCols[colIndex]
  if (!col) return
  
  startWidth.value = col.offsetWidth
  currentColumn.value = { headerCol: col, bodyCol: bodyCols[colIndex], index: colIndex }
  resizeLinePos.value = event.clientX - tableRef.value.getBoundingClientRect().left
  
  document.addEventListener('mousemove', handleResize)
  document.addEventListener('mouseup', stopResize)
}

const handleResize = (event) => {
  if (!resizing.value || !currentColumn.value) return
  
  const diff = event.clientX - startX.value
  const newWidth = Math.max(50, startWidth.value + diff)
  
  if (currentColumn.value.index === 'selection') {
    emit('update:selectionColumnWidth', `${newWidth}px`)
  } else {
    const newColumns = [...props.columns]
    newColumns[currentColumn.value.index].width = `${newWidth}px`
    emit('update:columns', newColumns)
  }
  
  resizeLinePos.value = event.clientX - tableRef.value.getBoundingClientRect().left
}

const stopResize = () => {
  resizing.value = false
  resizeLinePos.value = 0
  currentColumn.value = null
  document.removeEventListener('mousemove', handleResize)
  document.removeEventListener('mouseup', stopResize)
}

const { data, pageSize } = toRefs(props)

// 搜索功能
const searchKeyword = ref('')
const filteredData = computed(() => {
  if (!searchKeyword.value) return props.data
  const keyword = searchKeyword.value.toLowerCase()
  return props.data.filter(row =>
      props.columns.some(col =>
          String(row[col.dataIndex]).toLowerCase().includes(keyword)
      )
  )
})

// 排序处理
const sortedData = computed(() => {
  if (!props.sortable || !props.sortedColumn.field) return filteredData.value

  return [...filteredData.value].sort((a, b) => {
    const field = props.sortedColumn.field
    const order = props.sortedColumn.order === 'asc' ? 1 : -1
    return a[field] > b[field] ? order : -order
  })
})

// 分页处理
const totalPages = computed(() => Math.ceil(sortedData.value.length / props.pageSize))
const processedData = computed(() => {
  if (!props.pagination) return sortedData.value
  const start = (props.currentPage - 1) * props.pageSize
  const end = start + props.pageSize
  return sortedData.value.slice(start, end)
})

// 空状态显示
const showEmpty = computed(() => {
  return !props.loading &&
      processedData.value.length === 0 &&
      filteredData.value.length === 0
})

// 列数计算
const totalColumns = computed(() => {
  return props.columns.length + (props.rowSelection ? 1 : 0)
})

// 行选择功能
const allSelected = computed(() =>
    props.selectedRows.length === processedData.value.length && processedData.value.length > 0
)

function toggleRowSelection(row) {
  const selected = [...props.selectedRows]
  const index = selected.findIndex(r => r === row)
  if (index > -1) {
    selected.splice(index, 1)
  } else {
    selected.push(row)
  }
  emit('update:selectedRows', selected)
}

function toggleAllSelection(e) {
  const checked = e.target.checked
  emit('update:selectedRows', checked ? [...processedData.value] : [])
}

function isRowSelected(row) {
  return props.selectedRows.includes(row)
}

// 分页控制
function changePage(page) {
  if (page < 1 || page > totalPages.value) return
  emit('update:currentPage', page)
  emit('paginationChange', { currentPage: page, pageSize: props.pageSize })
}

// 排序处理
function handleSort(col) {
  if (!props.sortable || !col.sortable) return

  let order = 'asc'
  if (props.sortedColumn.field === col.dataIndex) {
    order = props.sortedColumn.order === 'asc' ? 'desc' : null
  }

  const newSort = order ?
      { field: col.dataIndex, order } :
      { field: null, order: null }

  emit('update:sortedColumn', newSort)
  emit('sortChange', newSort)
}

// 事件处理
function handleRowClick(row) {
  emit('rowClick', row)
}

function handleSearch() {
  if (props.pagination) {
    emit('update:currentPage', 1)
  }
}

// 样式类
const headerAlignClass = computed(() => `align-${props.headerAlign}`)
const cellAlignClass = computed(() => `align-${props.cellAlign}`)

// 添加同步滚动方法
const syncHeaderScroll = (e) => {
  const headerContainer = document.querySelector('.fixed-header-container')
  if(headerContainer) {
    headerContainer.scrollLeft = e.target.scrollLeft
  }
}

// 处理树形数据，将扁平化的数据转换为层级结构
const processTreeData = (data) => {
  if (!props.treeData) return data
  
  const result = []
  const traverse = (items, level = 0) => {
    items.forEach(item => {
      result.push({
        ...item,
        _level: level,
        _visible: level === 0 || props.expandedKeys.includes(item._parent?.id)
      })
      
      if (item.children?.length) {
        traverse(item.children, level + 1)
      }
    })
  }
  
  traverse(data)
  return result
}

// 计算实际显示的数据
const displayData = computed(() => {
  const processed = processTreeData(props.data)
  if (!props.treeData) return processed
  
  return processed.filter(item => {
    if (item._level === 0) return true
    
    let parent = item._parent
    while (parent) {
      if (!props.expandedKeys.includes(parent.id)) {
        return false
      }
      parent = parent._parent
    }
    return true
  })
})

// 导出数据处理
const getExportData = computed(() => {
  if (props.exportMode === 'all') {
    return props.data
  }
  return processedData.value
})

// 导出方法
const handleExport = () => {
  const data = getExportData.value.map(row => {
    const obj = {}
    props.columns.forEach(col => {
      obj[col.title] = row[col.dataIndex]
    })
    return obj
  })

  const worksheet = utils.json_to_sheet(data)
  const workbook = utils.book_new()
  utils.book_append_sheet(workbook, worksheet, "Sheet1")

  const fileType = props.exportType === 'xlsx' 
    ? 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' 
    : 'text/csv;charset=utf-8'

  const extension = props.exportType === 'xlsx' ? '.xlsx' : '.csv'
  const fileName = `${props.exportFileName}_${new Date().toISOString().slice(0,10)}${extension}`

  writeFile(workbook, fileName, { bookType: props.exportType })
}
</script>

<style scoped>
/* 新增列宽调整样式 */
.resize-handle {
  position: absolute;
  right: -2px;
  top: 0;
  bottom: 0;
  width: 4px;
  cursor: col-resize;
  z-index: 1;
  transition: background 0.2s;
  opacity: 0.5;
}

.resize-handle:hover,
.resize-handle:active {
  background: var(--resize-handle-color, #409eff);
}

/* 表头单元格样式调整 */
th {
  position: relative;
  overflow: visible;
}

.header-content {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  padding-right: 12px;
}

.ds-table {
  --header-bg: #f5f7fa;
  --border-color: #ebeef5;
  --hover-bg: #f5f7fa;
  --empty-text-color: #909399;
  --empty-icon-color: #c0c4cc;
}

table {
  width: 100%;
  border-collapse: collapse;
  background: white;
}

th, td {
  padding: 12px;
  border-bottom: 1px solid var(--border-color);
}

/* 对齐样式 */
.align-left { text-align: left; }
.align-center { text-align: center; }
.align-right { text-align: right; }

/* 斑马纹 */
.table-stripe tr:nth-child(even):not(.empty-row) {
  background-color: var(--header-bg);
}

/* 边框 */
.table-border {
  border: 1px solid var(--border-color);
}

/* 尺寸 */
.table-size-small th,
.table-size-small td {
  padding: 8px;
}

.table-size-large th,
.table-size-large td {
  padding: 16px;
}

/* 交互状态 */
tr:hover:not(.empty-row) {
  background-color: var(--hover-bg);
}

.selected-row {
  background-color: #e6f7ff !important;
}

/* 排序相关 */
.sort-icon {
  margin-left: 4px;
}

.sortable {
  cursor: pointer;
  user-select: none;
  transition: background 0.3s;
}

.sortable:hover {
  background: #f0f2f5;
}

/* 分页样式 */
.table-pagination {
  margin-top: 16px;
  display: flex;
  gap: 12px;
  align-items: center;
  justify-content: flex-end;
  padding: 8px 0;
}

.table-pagination button {
  padding: 6px 12px;
  border: 1px solid #ddd;
  background: white;
  border-radius: 4px;
  cursor: pointer;
}

/* 调整分页按钮禁用样式 */
.table-pagination button:disabled {
  background-color: #f5f7fa;
  cursor: not-allowed;
}

/* 搜索框样式 */
.search-input {
  margin-bottom: 16px;
  padding: 8px 12px;
  width: 240px;
  border: 1px solid #ddd;
  border-radius: 4px;
}

/* 空状态样式 */
.empty-row td {
  text-align: center;
  padding: 40px 0;
  border-bottom: none;
}

.empty-content {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  color: var(--empty-text-color);
}

.empty-icon {
  width: 80px;
  height: 80px;
  margin-bottom: 16px;
  fill: var(--empty-icon-color);
}

.empty-text {
  font-size: 14px;
}
/* 新增加载样式 */
.loading-mask {
  position: absolute;
  z-index: 100;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(255, 255, 255, 0.8);
  display: flex;
  align-items: center;
  justify-content: center;
}

.loading-content {
  text-align: center;
}

.default-loading {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  color: #409eff;
}

.loading-spinner {
  width: 40px;
  height: 40px;
  border: 3px solid #f3f3f3;
  border-radius: 50%;
  border-top-color: currentColor;
  animation: spin 1s linear infinite;
  margin-bottom: 8px;
}

.loading-text {
  font-size: 14px;
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

/* 新增表头固定样式 */
.table-container {
  position: relative;
  height: 100%;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

.fixed-header-container {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  z-index: 2;
  background: white;
  overflow: hidden;
  height: 41px;  /* 固定表头高度 */
}

.body-container {
  height: 100%;
  overflow: auto;
  padding-top: 41px;  /* 为固定表头留出空间 */
}

.header-table,
.body-table {
  table-layout: fixed;
  width: 100%;
}

.header-table th {
  background: var(--header-bg);
  position: sticky;
  top: 0;
}

/* 调整表头单元格高度 */
.fixed-header-container th {
  padding: 12px;
  border-bottom: 1px solid var(--border-color);
}

.tree-indent {
  display: inline-block;
}

.expanded-row {
  background-color: #fafafa;
}

.expanded-row > td {
  padding: 0;
  border-bottom: 1px solid #ebeef5;
}

/* 导出按钮样式 */
.table-export {
  margin-bottom: 16px;
}

.table-export button {
  padding: 8px 16px;
  background: #409eff;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  transition: background 0.3s;
}

.table-export button:hover {
  background: #66b1ff;
}
</style>